package com.bbcare.followup.plat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bbcare.comm.*;
import com.bbcare.department.plat.service.impl.DepartmentBasicService;
import com.bbcare.followup.plat.entity.*;
import com.bbcare.followup.plat.store.ibatis.*;
import com.bbcare.treat.plat.service.impl.PatientArchService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @name: 小程序消息业务处理类
 * @author: czy
 * @createTime: 2019.5.23
 * @description: 小程序消息业务处理
 * @modify:
 */
@Service
public class SmallProgramService {
    private final Log logger = LogFactory.getLog(SmallProgramService.class);

    @Autowired
    private IPatientDAO iPatientDAO;

    @Autowired
    private IPatientTaskDAO iPatientTaskDAO;

    @Autowired
    private IFollowQueueDAO iFollowQueueDAO;

    @Autowired
    private IPatientQueueSchemeDAO iPatientQueueSchemeDAO;

    @Autowired
    private IPatientAppointmentDAO iPatientAppointmentDAO;

    @Autowired
    private PatientService patientSerivce;

    @Autowired
    private PatientArchService patientArchService;

    @Autowired
    private FollowQueueService followQueueSerivce;

    @Autowired
    private DepartmentBasicService departmentBasicService;

    public void MqttBusiness(String receiveMsg) throws Exception {

        String sendMsg = null;

        JSONObject jsonArg = JSON.parseObject(receiveMsg);

        // 小程序消息队列传入的type，判断是2.0建档还是3.0建档
        // 1作为2.0建档，3作为3.0建档
        // 8作为2.0随访门诊预约类型
        String type = jsonArg.getString("type");
        // code判断是否为发送消息
        String code = jsonArg.getString("code");
        if (("1").equals(type) && code == null) {

            // 获取问卷内容
            Map<String, Object> quesMap = new HashMap<String, Object>();
            quesMap = jsonArg.getJSONObject("content");

            String userId = jsonArg.getString("userId");
            String userIdNew ="";
            String queueId = jsonArg.getString("queueId");
            Map<String, Object> map = new HashMap<String, Object>();
            Map<String, Object> chkMapIn = new HashMap<String, Object>();
            boolean isVerify = true;
            map.put("id", queueId);
            chkMapIn.put("queueId", queueId);
            FollowQueue queue = followQueueSerivce.getQueueDetailByQueueId(map);
            if (null == queue) {
                sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_QUEUE_NOT_EXIST + "\",\"msg\":\"根据队列id查询无此队列信息！\",\"userId\":\"" + userId + "\"}";
                HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_QUEUE_NOT_EXIST, "根据队列id查询无此队列信息！"));
            }

            String queueUserType = queue.getQueueUsertype();

            Map<String, Object> servParamMap = new HashMap<String, Object>();

            String author = "小程序建档";
            String authorName = "同步小程序建档";
            String tenantId = queue.getTenantId();
            String deptId = queue.getDeptId();

            // 操作编码默认：1000（患者建档）
            String opCode = "1000";
            // 操作类型默认：2（门诊）
            String opType = "2";
            // 患者来源渠道默认：9（小程序建档）
            String sourceType = Constants.PATIENT_SOURCE_TYPE_MINI_PROGRAM;
            String opNote = "小程序建档";
            // 创建时间
            String currTime = DateUtil.getTimeString(DateUtil.getSysDateA());

            String userType = null;
            if (Constants.QUEUE_USER_TYPE_BABY.equals(queueUserType)) {
                // 宝宝
                userType = "1";
                servParamMap.put("userType", userType);
            } else if (Constants.QUEUE_USER_TYPE_PARTURIENT.equals(queueUserType)) {
                // 孕产妇
                userType = "2";
                servParamMap.put("userType", userType);
            } else if (Constants.QUEUE_USER_TYPE_OTHER.equals(queueUserType)) {
                // 其他
                userType = "3";
                servParamMap.put("userType", userType);
            }

            Map<String, Object> userMap = new HashMap<>();

            String updateAccept = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID);// 操作流水

            String phoneNum = null;
            if (StringUtils.isBlank(phoneNum)) {
                if (null != quesMap && 0 != quesMap.size()) {
                    phoneNum = (String) quesMap.get(Constants.QUESTION_ID_FOR_PHONENO);
                }
            }
            if (StringUtils.isBlank(phoneNum)) {
                phoneNum = "";
                chkMapIn.put("quesId", Constants.QUESTION_ID_FOR_PHONENO);
                isVerify = patientArchService.isVerifyArchiveParam(chkMapIn);
                if (isVerify) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR + "\",\"msg\":\"手机号码不能为空！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "手机号码不能为空！"));
                }
            }
            phoneNum = phoneNum.trim();

            String patientName = null;
            if (StringUtils.isBlank(patientName)) {
                if (null != quesMap && 0 != quesMap.size()) {
                    patientName = (String) quesMap.get(Constants.QUESTION_ID_FOR_PATIENTNAME);
                }
            }
            if (StringUtils.isBlank(patientName)) {
                patientName = "";
                chkMapIn.put("quesId", Constants.QUESTION_ID_FOR_PATIENTNAME);
                isVerify = patientArchService.isVerifyArchiveParam(chkMapIn);
                if (isVerify) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR + "\",\"msg\":\"患者姓名不能为空！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "患者姓名不能为空！"));
                }
            }
            patientName = patientName.trim();

            String gender = null;
            if (Constants.QUEUE_USER_TYPE_PARTURIENT.equals(queueUserType)) {
                // 孕产妇（母亲）
                gender = Constants.GENDER_FOR_FEMALE;
            } else if (StringUtils.isBlank(gender)) {
                if (null != quesMap && 0 != quesMap.size()) {
                    gender = (String) quesMap.get(Constants.QUESTION_ID_FOR_GENDER);
                }
            }
            if (StringUtils.isBlank(gender)) {
                gender = "";
                chkMapIn.put("quesId", Constants.QUESTION_ID_FOR_GENDER);
                isVerify = patientArchService.isVerifyArchiveParam(chkMapIn);
                if (isVerify) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR + "\",\"msg\":\"性别不能为空！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "性别不能为空！"));
                }
            }
            gender = gender.trim();
            // 转换性别
            if (Constants.GENDER_ALIAS_FOR_MALE.equals(gender)) {
                gender = Constants.GENDER_FOR_MALE;
            } else if (Constants.GENDER_ALIAS_FOR_FEMALE.equals(gender)) {
                gender = Constants.GENDER_FOR_FEMALE;
            } else if (!Constants.GENDER_FOR_MALE.equals(gender) && !Constants.GENDER_FOR_FEMALE.equals(gender)) {
                gender = Constants.GENDER_FOR_MALE;
            }

            String birthday = null;
            if (StringUtils.isBlank(birthday)) {
                if (null != quesMap && 0 != quesMap.size()) {
                    birthday = (String) quesMap.get(Constants.QUESTION_ID_FOR_BIRTHDAY);
                    // Excel获取年龄格式为yyyy-MM-dd HH:mm:ss处理成yyyy-MM-dd格式，方便后续时间节点计算
                    String[] birthdays = birthday.split(" ");
                    birthday = birthdays[0];
                }
            }
            if (StringUtils.isBlank(birthday) && !Constants.QUEUE_USER_TYPE_PARTURIENT.equals(queueUserType)) {
                birthday = null;
                chkMapIn.put("quesId", Constants.QUESTION_ID_FOR_BIRTHDAY);
                isVerify = patientArchService.isVerifyArchiveParam(chkMapIn);
                if (isVerify) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR + "\",\"msg\":\"出生日期不能为空！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "出生日期不能为空！"));
                }
            }

            // 预产期
            String expectedDay = null;
            if (StringUtils.isBlank(expectedDay)) {
                if (null != quesMap && 0 != quesMap.size()) {
                    expectedDay = (String) quesMap.get(Constants.QUESTION_ID_FOR_EXPECTEDDAY);
                }
            }
            if (StringUtils.isEmpty(expectedDay)) {
                expectedDay = null;
            }

            // 出生胎龄(孕周)
            int pregnancyDay = 0;
            // 再考虑从问卷中获取，问卷存储格式天
            if (pregnancyDay <= 0 && !MapUtils.isEmpty(quesMap)) {
                pregnancyDay = Integer.parseInt((String) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCYDAY));
//                                String preStr = (String) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCYDAY);
//                                if (!StringUtils.isBlank(preStr)) {
//                                    String preArr[] = preStr.split(Constants.COMMA_SPLIT_STR);
//                                    if (null != preArr && 2 == preArr.length) {
//                                        String preWeekStr = preArr[0].substring(1);
//                                        String preDayStr = preArr[1].substring(0, preArr[1].length() - 1);
//                                        int preWeek = Integer.parseInt(preWeekStr);
//                                        int preDay = Integer.parseInt(preDayStr);
//                                        pregnancyDay = preWeek * Constants.PREGNANCY_CALC_UNIT_WEEK + preDay;
//                                    }
//                                }
            }
            // 最后根据根据生日和预产期计算
            if (Constants.QUEUE_USER_TYPE_PARTURIENT.equals(queueUserType)) {
                // 孕产妇（母亲）
                // 初检孕周
                String firstChkPregWeek = (String) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCY_FIRST_WEEK);
                if (StringUtils.isBlank(firstChkPregWeek)) {
                    // 不在这里校验，在实例化随访任务时校验
                } else {
                    servParamMap.put("firstChkPregWeek", Integer.parseInt(firstChkPregWeek));
                }
                // 末次月经日期
                String lastMenstruationDate = (String) quesMap.get(Constants.QUESTION_ID_FOR_LAST_MENSTRUATION_DATE);
                if (StringUtils.isBlank(lastMenstruationDate)) {
                    // 不在这里校验，在实例化随访任务时校验
                } else {
                    servParamMap.put("lastMenstruationDate", lastMenstruationDate);
                }
                // 分娩日期
                servParamMap.put("deliveryDate", quesMap.get(Constants.QUESTION_ID_FOR_LAST_DELIVERY_DATE));
            } else if (pregnancyDay <= 0 && !StringUtils.isBlank(expectedDay)) {
                pregnancyDay = ToolUtils.calPrenDayByBirthAndExpect(birthday, expectedDay);
            }

            // 孕周未填，默认280
            if (pregnancyDay <= 0) {
                pregnancyDay = Constants.PATIENT_NORMAL_PREGNANT_DAY;
            }
            // 预产期未填，默认与出生日期一致
            if (StringUtils.isBlank(expectedDay)) {
                expectedDay = birthday;
            }

            if (pregnancyDay > 321) {
                sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR + "\",\"msg\":\"出生日期或者预产期不正确，请检查！\",\"userId\":\"" + userId + "\"}";
                HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                        "尊敬的用户，您填写的出生日期或者预产期不正确，请检查！");
            }

            // 防止重复新建患者
            Map<String, Object> qryPtMap = new HashMap<String, Object>();
            qryPtMap.put("phoneNo", phoneNum);
            qryPtMap.put("userName", patientName);
            qryPtMap.put("tenantId", tenantId);
            // 不同类型用户
            qryPtMap.put("userType", userType);
            List<Patient> ptList = iPatientDAO.selectByPhoneNo(qryPtMap);
            List<PatientQueueScheme> pqsList = new ArrayList<PatientQueueScheme>();
            if (!org.springframework.util.CollectionUtils.isEmpty(ptList)) {
                // 校验患者是否已经加入过该队列
                HashMap<String, Object> qryPqsMap = new HashMap<String, Object>();
                qryPqsMap.put("userId", ptList.get(0).getId());
                qryPqsMap.put("queueId", queueId);

                List<String> statulist = new ArrayList<String>();

                statulist.add(Constants.PATIENT_QUEUESCHEME_USER_STATUS_NOMAL);

                qryPqsMap.put("status", statulist);

                pqsList = iPatientQueueSchemeDAO.selectByUserId(qryPqsMap);
            }

            if (org.springframework.util.CollectionUtils.isEmpty(pqsList)) {
                Patient pt = new Patient();

                pt.setPregnancyDay(pregnancyDay);
                pt.setUserName(patientName);
                pt.setPhoneNo(phoneNum);
                pt.setFirstName(patientName.substring(0, 1));
                pt.setCreateTime(currTime);
                pt.setUpdateTime(currTime);
                pt.setCreateAuthor(author);
                pt.setBirthday(birthday);
                pt.setExpectedDay(expectedDay);
                pt.setGender(gender);
                pt.setUserType(userType);
                pt.setSourceType(sourceType);

                try {
                    servParamMap.put("patient", pt);
                    servParamMap.put("authorName", authorName);
                    servParamMap.put("deptId", deptId);
                    servParamMap.put("queueId", queueId);
                    servParamMap.put("updateTime", currTime);
                    servParamMap.put("authorId", author);
                    servParamMap.put("updateAccept", updateAccept);
                    servParamMap.put("tenantId", tenantId);
                    servParamMap.put("opCode", opCode);
                    servParamMap.put("opNote", opNote);
                    servParamMap.put("opType", opType);
                    servParamMap.put("contentData", quesMap);
                    userMap = patientSerivce.registerPatient(servParamMap);
                    userIdNew = (String) userMap.get("patientId");
                    quesMap.clear();
                } catch (Exception e) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.SMALL_PROGRAM_EXCEPTION_ARCHIVE_FAILURE + "\",\"msg\":\"同步建档失败！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw new AppException(ErrorCode.SMALL_PROGRAM_EXCEPTION_ARCHIVE_FAILURE,
                            "同步建档失败！");
                }
            } else {
                sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.SMALL_PROGRAM_EXCEPTION_ARCHIVE_FAILURE + "\",\"msg\":\"该类型用户在该队列下已建过档，不能重复建档！\",\"userId\":\"" + userId + "\"}";
                HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
            }

            if (!userMap.isEmpty()) {
                String platType = departmentBasicService.getDepartmentBasicDetails(deptId).getPlatType();
                sendMsg = "{\"type\":" + type + ",\"deptId\":\"" + deptId + "\",\"code\":\"0\",\"msg\":\"同步建档成功！\",\"userId\":\"" + userIdNew + "\",\"tenantId\":\"" + tenantId + "\",\"platType\":"+
                        platType+",\"oriUserId\":\""+userId+"\"}";
                HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
            }
        } else if (("8").equals(type) && code == null) {
            String taskName = null;
            String queueId = null;
            String tenantId = null;
            // 预约状态默认1
            String appointmentState = "1";
            // 预约类型暂定默认为1（门诊随访预约），后续待扩展
            String appointmentType = "1";
            String appointmentRemark = "小程序端预约";
            String orderTime = jsonArg.getString("orderTime");
            String userId = jsonArg.getString("userId");
            Map<String, Object> map = new HashMap<String, Object>();

            map.put("userId", userId);
            Patient patient = iPatientDAO.selectById(map);

            if (patient == null) {
                sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_NOT_EXIST + "\",\"msg\":\"查询患者记录不存在！\",\"userId\":\"" + userId + "\"}";
                HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_NOT_EXIST,
                        "查询患者记录不存在！");
            }

            String taskId = jsonArg.getString("taskId");
            map.put("taskId", taskId);

            List<PatientTask> patientTask = iPatientTaskDAO.selectById(map);
            if (patientTask.size() == 0 || patientTask == null) {
                sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_TASK_NOT_EXIST + "\",\"msg\":\"查询患者任务记录不存在！\",\"userId\":\"" + userId + "\"}";
                HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_TASK_NOT_EXIST,
                        "查询患者任务记录不存在！");
            }

            taskName = patientTask.get(0).getTaskName();
            queueId = patientTask.get(0).getQueueId();

            map.clear();
            map.put("id", queueId);

            List<FollowQueue> followQueues = iFollowQueueDAO.selectById(map);
            tenantId = followQueues.get(0).getTenantId();

            map.clear();
            map.put("taskId", taskId);
            List appointment = iPatientAppointmentDAO.selectPatientAppointment(map);

            if (appointment.isEmpty()) {
                PatientAppointment patientAppointment = new PatientAppointment();

                patientAppointment.setId(SeqUtil.getSeqNo());
                patientAppointment.setUserId(userId);
                patientAppointment.setPhoneNo(patient.getPhoneNo());
                patientAppointment.setPersenName(patient.getUserName());
                patientAppointment.setTaskId(taskId);
                patientAppointment.setTaskName(taskName);
                patientAppointment.setTenantId(tenantId);
                patientAppointment.setQueueId(queueId);
                patientAppointment.setAppointmentState(appointmentState);
                patientAppointment.setAppointmentType(appointmentType);
                patientAppointment.setAppointmentTime(orderTime);
                patientAppointment.setRemark(appointmentRemark);
                patientAppointment.setExtendedField1(null);
                patientAppointment.setExtendedField2(null);
                patientAppointment.setExtendedField3(null);

                int addnumber = iPatientAppointmentDAO.savePatientAppointment(patientAppointment);

                if (addnumber > 0) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"0\",\"msg\":\"预约成功！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                } else {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.SMALL_PROGRAM_APPONITMENT_FAILURE + "\",\"msg\":\"预约失败！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw new AppException(ErrorCode.SMALL_PROGRAM_APPONITMENT_FAILURE,
                            "预约失败！");
                }
            } else {
                map.put("appointmentState", appointmentState);
                map.put("appointmentTime", orderTime);
                map.put("remark", "患者本人修改预约时间！");
                int updatenumber = iPatientAppointmentDAO.updateDataById(map);

                if (updatenumber > 0) {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"0\",\"msg\":\"修改时间成功！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                } else {
                    sendMsg = "{\"type\":" + type + ",\"code\":\"" + ErrorCode.SMALL_PROGRAM_APPONITMENT_FAILURE + "\",\"msg\":\"修改时间失败！\",\"userId\":\"" + userId + "\"}";
                    HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl") ,sendMsg);
                    throw new AppException(ErrorCode.SMALL_PROGRAM_APPONITMENT_FAILURE,
                            "修改时间失败！");
                }
            }

        } else {
            logger.info("不是2.0建档或2.0随访门诊预约，不做处理！");
        }
    }
}
